<?php

/**
 * 返回json结果集
    1xx    处理信息，服务器收到请求，需要请求者继续执行操作；
    2xx    请求成功，操作被成功接收并处理；
    3xx    重定向，需要进一步的操作以完成请求；
    4xx    客户端错误，请求包含语法错误或无法完成请求；
    5xx    服务器错误，服务器在处理请求的过程中发生了错误；
 * @param  int $code [description] 状态码
 * @param  string $msg [description] 提示信息
 * @param  array $data [description] 数据集
 * @param  array $to_json [description] 是否转json
 * @return [type]       [description] json集合
 */
function result_json(int $code, string $msg, array $data = [], bool $to_json = false)
{
    // 根据状态码获取状态信息
    $status = function () use ($code) {
        switch ($code) {
            case 200:
                $status = 'Success';
                break;
            case 400:
                $status = 'Bad Request';
                break;
            case 409:
                $status = 'Bad Request';
                break;
            case 500:
                $status = 'INTERNAL_ERROR';
                break;
            default:
                $status = 'Unknown Code';
                break;
        }
        return $status;
    };

    $data_arr = ['code' => $code, 'msg' => $msg, 'data' => $data, 'status' => $status()];
    $result = $to_json == true ? json_encode($data_arr) : $data_arr;
    \Illuminate\Support\Facades\Log::info('请求数据返回:', $data_arr);
    return $result;
}


/**
 * 上传图像
 * @param $file
 * @param $path 上传路径
 * @return array|string
 */
function upload_img($file, $path)
{
    if (!$file || !$path) return result_json(400, '参数错误');
    $url_path = "storage/uploads/images/{$path}/" . date('Y-m-d');
    $ext_arr = ['jpg', 'jpeg', 'png'];

    if (!$file->isValid()) return result_json(409, '图片无效');
    $client_name = $file->getClientOriginalName();
    $size = $file->getSize();
//    $type = $file->getClientMimeType();     // image/jpeg
//    $tmpName = $file->getFileName();
//    $realPath = $file->getRealPath();
    $ext = $file->getClientOriginalExtension();
    if (!in_array($ext, $ext_arr)) return result_json(409, '图片格式为jpg,jpeg,png');
    if ($size > 2 * 1024 * 1024) return result_json(409, '图片大小不能超过2M');

    $new_wame = md5(date("Y-m-d H:i:s") . $client_name) . "." . $ext;
    $path = $file->move($url_path, $new_wame);
    if (!$path) return result_json(500, '上传失败');
    $save_path = $url_path . '/' . $new_wame;
    return result_json(200, '上传成功', ['file_path' => $save_path]);

}

/**
 * 获取接口分页数据
 * @param $list
 * @return array
 */
function get_paging_data($list)
{
    $data = [
        'items' => $list['data'],
        'current_page' => $list['current_page'],
        'total' => $list['total'],
        'last_page' => $list['last_page'],
    ];
    return $data;
}


/**
 * 随机字符串
 * @param int $randLength
 * @param int $addtime
 * @param int $includenumber
 * @return string
 */
function rand_str($randLength = 6, $addtime = 0, $includenumber = 0)
{
    if ($includenumber) {
        $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQEST123456789';
    } else {
        $chars = 'abcdefghijklmnopqrstuvwxyz';
    }
    $len = strlen($chars);
    $randStr = '';
    for ($i = 0; $i < $randLength; $i++) {
        $randStr .= $chars[mt_rand(0, $len - 1)];
    }
    $tokenvalue = $randStr;
    if ($addtime) {
        $tokenvalue = $randStr . time();
    }
    return $tokenvalue;
}


/**
 * 随机数字
 * @param int $length
 * @return string
 */
function rand_number($length = 6)
{
    $number = '';
    for ($i = 0; $i < $length; $i++) {
        $number .= mt_rand(0, 9);
    }
    return $number;
}

/**
 * 获取唯一订单编号
 * @param $sign
 * @return string
 */
function get_order_code($sign)
{
    $date = date("His");
    $code = 1 . $sign . $date . rand_number(4);
    return $code;
}


/**
 * 计算多个集合的笛卡尔积
 * @param  Array $sets 集合数组
 * @return Array
 */
function cartesian_product($sets)
{

    // 保存结果
    $result = array();
    $count = count($sets);
    if ($count == 1) return $sets[0];
    // 循环遍历集合数据
    for ($i = 0; $i < $count - 1; $i++) {

        // 初始化
        if ($i == 0) {
            $result = $sets[$i];
        }

        // 保存临时数据
        $tmp = array();

        // 结果与下一个集合计算笛卡尔积
        foreach ($result as $res) {
            foreach ($sets[$i + 1] as $set) {
                $tmp[] = $res . ',' . $set;
            }
        }

        // 将笛卡尔积写入结果
        $result = $tmp;

    }

    return $result;

}

/**
 * 检测数组是否有空值
 * @param $arr
 * @return bool
 */
function array_null($arr)
{
    if (!is_array($arr)) return false;
    foreach ($arr as $k => $v) {
        if (is_array($v)) {
            $t = array_null($v);
            if (!$t) return false;
        }
        if ($v === "" && !is_array($v)) {
            return false;
        }
    }
    return true;
}

/**
 * 获取数组中最小或最大值
 * @param $arr
 * @param $field
 * @param $type
 * @return int
 */
function get_array_value($arr, $field, $type)
{
    $data = array_column($arr, $field);
    switch ($type) {
        case 'min':
            $result = min($data);
            break;
        case 'max':
            $result = max($data);
            break;
        default:
            $result = 0;
            break;
    }
    return $result;
}

/**
 * 获取两个时间区间的日期列表
 * @param $start_date
 * @param $end_date
 * @return array
 */
function getDateDayArr($start_date, $end_date)
{
    $start_timestamp = strtotime($start_date);
    $end_timestamp = strtotime($end_date);
    $day_arr = [];
    while ($start_timestamp <= $end_timestamp) {
        $new_date = date('Y-m-d', $start_timestamp);
        $day_arr[] = $new_date;
        $start_timestamp += 60 * 60 * 24;
    }
    return $day_arr;
}

/**
 * 获取一天中的每个时辰列表
 * @param $start_date
 * @param $end_date
 * @return array
 */
function getDayHourArr($date)
{
    $date_timestamp = strtotime($date);
    $tommorrow_timestamp = strtotime($date) + (60 * 60 * 24 - 60 * 60);
    $arr = [];
    while ($date_timestamp <= $tommorrow_timestamp) {
        $hour = date('H:i', $date_timestamp);
        $arr[] = $hour;
        $date_timestamp += 60 * 60;
    }
    return $arr;
}


/**
 * 计算两点之间的距离
 * @param $lng1 经度1
 * @param $lat1 纬度1
 * @param $lng2 经度2
 * @param $lat2 纬度2
 * @param int $unit m，km
 * @param int $decimal 位数
 * @return float
 */
function getDistance($lng1, $lat1, $lng2, $lat2, $unit = 2, $decimal = 2)
{

    $EARTH_RADIUS = 6370.996; // 地球半径系数
    $PI           = 3.1415926535898;

    $radLat1 = $lat1 * $PI / 180.0;
    $radLat2 = $lat2 * $PI / 180.0;

    $radLng1 = $lng1 * $PI / 180.0;
    $radLng2 = $lng2 * $PI / 180.0;

    $a = $radLat1 - $radLat2;
    $b = $radLng1 - $radLng2;

    $distance = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2)));
    $distance = $distance * $EARTH_RADIUS * 1000;

    if ($unit === 2) {
        $distance /= 1000;
    }

    return round($distance, $decimal);
}